package m08;

import javax.imageio.ImageIO;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import java.awt.Color;
import javax.swing.border.LineBorder;
import m06.SolarSystem;
import m07.GamePanel;
import m09.Global;
import m09.RandomEncounterFrame;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

/**
 * This class allows the user to switch the solar system they are in,
 * changes the market for that solar system and 
 * lets them know their current location
 * 
 * @author Eric Hamilton
 * @version 3.2
 *
 */
public class MapPanel extends JPanel implements Serializable{
	private static final long serialVersionUID = -3842344305257054960L;
	private SolarSystem sso = new SolarSystem();
	public JComboBox choice = new JComboBox();
	private JButton goButton = new JButton("GO!");
	private JLabel label = new JLabel("Current Solar System: Demeter");	
	private Icon shipIcon;

	public ArrayList<String> sysList = new ArrayList<String>();

	private String ss01;
	private String ss02;
	private String ss03;
	private String ss04;
	private String ss05;
	private String ss06;
	private String ss07;
	private String ss08;
	private String ss09;
	private int dist;
	private int currentSys = 2;
	private int techNum = 1;


	private final GamePanel gp;
	private JLabel picLabel;

	/**
	 * This method creates the panel for changing Solar Systems.
	 * @param curPlayer the current player.
	 */
	public MapPanel(GamePanel gp) {
		this.gp = gp;
		picLabel = new JLabel();
		gp.add(picLabel);
		ss01 = sso.ss01.getName();
		ss02 = sso.ss02.getName();
		ss03 = sso.ss03.getName();
		ss04 = sso.ss04.getName();
		ss05 = sso.ss05.getName();
		ss06 = sso.ss06.getName();
		ss07 = sso.ss07.getName();
		ss08 = sso.ss08.getName();
		ss09 = sso.ss09.getName();
		setBorder(new LineBorder(new Color(0, 0, 0), 1, true));
		setLayout(null);
		List<String> destinationList = new ArrayList<String>();
		choice.setBounds(300, 360, 246, 26);
		destinationList.add("Select a Destination");
		destinationList.add("Titan");
		destinationList.add("Demeter");
		destinationList.add("Apollo");
		destinationList.add("Schwagger");
		destinationList.add("Argus");
		destinationList.add("Nix");
		destinationList.add("Xerox");
		destinationList.add("Isis");
		destinationList.add("Brax");
		for (int i = 0; i < destinationList.size(); ++i) {
			choice.insertItemAt(destinationList.get(i), i);
		}
		choice.setSelectedIndex(0);
		gp.add(choice);
		mapImgSet(currentSys);

		/**
		 * this method is the MouseListener for the goButton
		 */
		goButton.addMouseListener(new MouseAdapter() {
			final GamePanel gp = getGP();
			@Override
			
			/**
			 * this is for the GO! button and changing solar systems
			 */
			public void mousePressed(MouseEvent arg0) {
				if(choice.getSelectedIndex() == 0) {
					errorScreen("", 2);
				}
				else if(choice.getSelectedIndex() == currentSys) {
					errorScreen("", 2);
				}
				else if(choice.getSelectedIndex() > 0) {
					dist = distCalc(sysChooser(currentSys), sysChooser(choice.getSelectedIndex()));
					if(Global.currentPlayer.getShip().getFuel() >= dist) {
						mapGen(choice.getSelectedItem().toString());
						currentSys = choice.getSelectedIndex();
						Global.currentPlayer.getShip().setFuelFromDist(dist);
						gp.updateFuel();
						mapImgSet(currentSys);
						updateMarket(marketLevel());
						Random sometimes = new Random();
						int willEncounter = sometimes.nextInt(10);
						if (willEncounter < 8){
							RandomEncounterFrame ref = new RandomEncounterFrame(gp);
							ref.setVisible(true);
						}
						
					}
					else{
						errorScreen(choice.getSelectedItem().toString(), 1);
					}

				}
			}
		});

		//button for going to another Solar System
		goButton.setBounds(300, 325, 79, 28);
		gp.add(goButton);

		//This label tells the user their current location
		label.setBounds(20, 240, 237, 19);
		label.setForeground(Color.white);
		gp.add(label);
		
		BufferedImage myPicture2;
		try {
			ClassLoader classLoader2 = Thread.currentThread().getContextClassLoader();
			InputStream input2 = classLoader2.getResourceAsStream("main_screen.png");
			myPicture2 = ImageIO.read(input2);
			JLabel picLabel2 = new JLabel(new ImageIcon(myPicture2));
			picLabel2.setBounds(0, 0, 900, 600);
			gp.add(picLabel2);
		} catch (IOException e) {
			e.printStackTrace();
			System.out.println("Background Not Loaded");
		}
	}
	
	/**
	 * a getter for the gamePanel.
	 * @return the game panel
	 */
	private GamePanel getGP(){
		return gp;
	}
	
	/**
	 * This method creates pop-up windows if the user makes an error
	 * 
	 * @param msg The system name to display in the error
	 * @param num the error number
	 */
	public void errorScreen(String msg, int num) {
		BufferedImage ship;
		try {
			ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
			InputStream input = classLoader.getResourceAsStream("ship.png");
			ship = ImageIO.read(input);
			shipIcon = new ImageIcon(ship);
		} catch (IOException e) {
			e.printStackTrace();
			System.out.println("Icon Not Loaded");
		}
		if(num == 1){
			final ImageIcon icon = new ImageIcon("");
	        JOptionPane.showMessageDialog(null, "You do not have enough fuel to reach " + msg + ".", "Message", JOptionPane.INFORMATION_MESSAGE, shipIcon);
		}
		if(num == 2){
			JOptionPane.showMessageDialog(null, "Please make a selection.", "Message", JOptionPane.INFORMATION_MESSAGE, shipIcon);
		}
	}

	/**
	 * This method sets the label for the current solar system
	 * 
	 * @param name the solar system the user is searching for
	 */
	public void mapGen(String name){
		sysList.add(ss01);
		sysList.add(ss02);
		sysList.add(ss03);
		sysList.add(ss04);
		sysList.add(ss05);
		sysList.add(ss06);
		sysList.add(ss07);
		sysList.add(ss08);
		sysList.add(ss09);

		for(int i=0; i < sysList.size(); i++){
			if(sysList.get(i).equals(name)){
				label.setText("Current Solar System: " + name);
			}
		}
	}

	/**
	 * This method calculates the distance between two solar systems
	 * 
	 * @param curr the current ss
	 * @param dest the destination solar system
	 * @return dist the new calculated distance
	 */
	public int distCalc(SolarSystem curr, SolarSystem dest){
		//calculate distances from all other SS
		int currX = curr.getXLocation();
		int currY = curr.getYLocation();
		int destX = dest.getXLocation();
		int destY = dest.getYLocation();
		dist = (int)(Math.abs(Math.sqrt((destX-currX)*(destX-currX) + (destY-currY)*(destY-currY))));
		dist /= 12;
		return dist;
	}

	/**
	 * This method returns the Solar System object found at the inputed index
	 * 
	 * @param num the index of the SS in the choice menu
	 * @return the solar system object
	 */
	public SolarSystem sysChooser(int num){
		if(num == 1) {
			return sso.ss01;
		}
		if(num == 2) {
			return sso.ss02;
		}
		if(num == 3) {
			return sso.ss03;
		}
		if(num == 4) {
			return sso.ss04;
		}
		if(num == 5) {
			return sso.ss05;
		}
		if(num == 6) {
			return sso.ss06;
		}
		if(num == 7) {
			return sso.ss07;
		}
		if(num == 8) {
			return sso.ss08;
		}
		if(num == 9) {
			return sso.ss09;
		}
		else{
			return null;
		}
	}

	/**
	 * This method converts the name of a tech level to its numeric representation
	 * 
	 * @return the number of the tech level
	 */
	public int marketLevel(){
		if(choice.getSelectedIndex() == 0){
			return techNum;
		}
		else {
			String techLevel = sysChooser(choice.getSelectedIndex()).getTechLevel();
			if(techLevel.equalsIgnoreCase("Pre-Agriculture"))
				techNum = 0;
			if(techLevel.equalsIgnoreCase("Agriculture"))
				techNum = 1;
			if(techLevel.equalsIgnoreCase("Medieval"))
				techNum = 2;
			if(techLevel.equalsIgnoreCase("Renaissance"))
				techNum = 3;
			if(techLevel.equalsIgnoreCase("Early Industrial"))
				techNum = 4;
			if(techLevel.equalsIgnoreCase("Industrial"))
				techNum = 5;
			if(techLevel.equalsIgnoreCase("Post Industrial"))
				techNum = 6;
			if(techLevel.equalsIgnoreCase("Hi-Tech"))
				techNum = 7;
		}
		return techNum;
	}

	/**
	 * This method updates the market in the new solar system to match the price changes
	 * 
	 * @param techNum the number representation of a tech level
	 */
	public void updateMarket(int techNum) {
		gp.waterGood.updatePrice(techNum);
		gp.furGood.updatePrice(techNum);
		gp.furGood.updatePrice(techNum);
		gp.oreGood.updatePrice(techNum);
		gp.gamesGood.updatePrice(techNum);
		gp.fireGood.updatePrice(techNum);
		gp.medsGood.updatePrice(techNum);
		gp.machineGood.updatePrice(techNum);
		gp.narcGood.updatePrice(techNum);
		gp.robotGood.updatePrice(techNum);

		gp.waterP.setText(gp.waterGood.getCurrentPrice() +" credits");
		gp.fursP.setText(gp.furGood.getCurrentPrice() +" credits");
		gp.foodP.setText(gp.foodGood.getCurrentPrice() +" credits");
		gp.oreP.setText(gp.oreGood.getCurrentPrice() +" credits");
		gp.gamesP.setText(gp.gamesGood.getCurrentPrice() +" credits");
		gp.firearmsP.setText(gp.fireGood.getCurrentPrice() +" credits");
		gp.medicineP.setText(gp.medsGood.getCurrentPrice() +" credits");
		gp.machinesP.setText(gp.machineGood.getCurrentPrice() +" credits");
		gp.narcoticsP.setText(gp.narcGood.getCurrentPrice() +" credits");
		gp.robotsP.setText(gp.robotGood.getCurrentPrice() +" credits");

		gp.updateBuyButtons();
		gp.updateSellButtons();

	}
	
	public void mapImgSet(int ss){
		BufferedImage map;
		try {
			ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
			InputStream input = classLoader.getResourceAsStream("SS0" + ss + "_2.png");
			map = ImageIO.read(input);
			ImageIcon icon = new ImageIcon(map);
			picLabel.setIcon(icon);
			picLabel.setBounds(20, 260, 250, 250);
		} catch (IOException e) {
			e.printStackTrace();
			System.out.println("Map Not Loaded");
		}
	}
	
	public SolarSystem getSS(){
		return sso;
	}
	
	public int getTechNum() {
		return techNum;
	}

	public void setTechNum(int techNum) {
		this.techNum = techNum;
	}
	
	public void setCurrentSys(int cs){
		currentSys = cs;
		choice.setSelectedIndex(cs);
		mapGen(choice.getItemAt(cs).toString());
		mapImgSet(cs);
	}
	
	public int getCurrentSys(){
		return currentSys;
	}
}
